package com.hanlink.dsp.ui;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.SparseArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProviders;

import com.blankj.utilcode.util.SPUtils;
import com.edge.pbx.ui.dialog.PbxLoadingDialog;
import com.edge.pbx.utils.PbxUploadReceiver;
import com.edge.pbx.view.home.PbxMainMenuRootLayout;
import com.edge.pbx.view.summing.PbxOutputSelectChannelsLayout;

import com.edge.pbxdsp.R;
import com.hanlink.dsp.DspContext;
import com.hanlink.dsp.DspSettings;

import com.hanlink.dsp.ca.ui.fragment.DelayFragment;
import com.hanlink.dsp.ca.ui.fragment.EqFragment;
import com.hanlink.dsp.ca.ui.fragment.GainFragment;
import com.hanlink.dsp.ca.ui.fragment.XoverFragment;
import com.hanlink.dsp.ui.activities.HomeViewModel;
import com.hanlink.dsp.ui.broadcast.UploadReceiver;
import com.edge.pbx.ui.dialog.AskAlertDialog;
import com.hanlink.dsp.ui.fragment.DeviceDialogFragment;
import com.hanlink.dsp.ui.fragment.SaveDialogFragment;
import com.hanlink.dsp.ui.fragment.Summing3Fragment;
import com.hanlink.dsp.util.BLog;
import com.hanlink.dsp.util.DataUtil;
import com.inuker.bluetooth.library.Constants;
import com.inuker.bluetooth.library.search.SearchResult;
import com.qztech.bluetooth.BluetoothClientManager;
import com.qztech.bluetooth.BluetoothConfig;
import com.qztech.bluetooth.event.BleConnectFailedEvent;
import com.qztech.bluetooth.event.BleConnectStatusEvent;
import com.qztech.bluetooth.event.BluetoothStateEvent;
import com.qztech.bluetooth.event.DeviceFoundedEvent;
import com.qztech.bluetooth.event.NotifyDataReadEvent;
import com.qztech.bluetooth.event.SearchStateEvent;
import com.qztech.sdk.ui.activities.BaseFragmentActivity;
import com.qztech.sdk.ui.fragment.BaseFragment;
import com.qztech.sdk.ui.fragment.SaveFragmentCallback;
import com.qztech.utils.YzDebug;


import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import static com.hanlink.dsp.util.Constants.KEY_LAST_EQCHART_TABID;
import static com.qztech.sdk.ui.fragment.BaseFragment.CMD_SELECTED;

@SuppressWarnings("unused")
public class CaAmpDspActivity extends BaseFragmentActivity implements SaveFragmentCallback {
    private PbxUploadReceiver uploadReceiver;


    //------Fragment------
    private Class<? extends BaseFragment>[] mTargetFragments = new Class[]{
            Summing3Fragment.class,//0
            XoverFragment.class,//1
            DelayFragment.class,//2
            GainFragment.class, //3
            EqFragment.class    //4
    };

    //-------Var-------
    private static int mTabId = 0;
    private String[] mResTitles;
    private HomeViewModel mHomeViewModel;
    private boolean mIsFoundDevice;
    private boolean mIsAutoConnect = true;
    private PbxMainMenuRootLayout mPbxMainMenuRootLayout;

    @Override
    protected int getResourceId() {
        return R.layout.activity_caampdsp;
    }

    @Override
    public boolean hasRegisterEventBus() {
        return true;
    }

    @Override
    protected void onCreate(final Bundle paramBundle) {

        super.onCreate(paramBundle);
        if (Build.VERSION.SDK_INT >= 21) {
            View decorView = getWindow().getDecorView();

            decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    |View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_FULLSCREEN);
/*            decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_FULLSCREEN);*/


          /*  decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_IMMERSIVE |
                            View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                            View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
                            View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
                            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
                            View.SYSTEM_UI_FLAG_FULLSCREEN);*/
            getWindow().setStatusBarColor(getResources().getColor(com.hanlink.res.R.color.common_tab_bg));
            getWindow().setNavigationBarColor(Color.TRANSPARENT);
        }

        mHomeViewModel = ViewModelProviders.of(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(HomeViewModel.class);
        mHomeViewModel.loadData();
        subscribeToViewModel();
        initView();
        initFragment();
        uploadReceiver = new PbxUploadReceiver(this);
        uploadReceiver.start();
        openShareFile();
        debug();

    }

    private void debug() {
        DisplayMetrics metrics = getResources().getDisplayMetrics();
        YzDebug.d("w:" + metrics.widthPixels + " " + " h:" + metrics.heightPixels
                + " dpi:" + metrics.densityDpi + " density:" + metrics.density +
                " wp:" + (metrics.widthPixels / metrics.density)
                + " hp:" + (metrics.heightPixels / metrics.density) + " " + metrics.scaledDensity +
                " -:" + getResources().getDimension(com.hanlink.res.R.dimen.chart_height));
    }


    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        openShareFile();
    }

    private void openShareFile() {
        Intent intent = getIntent();
        String action = intent.getAction();
        Uri uri = null;
        if (Intent.ACTION_VIEW.equals(action)) {
            uri = intent.getData();
        } else if (Intent.ACTION_SEND.equals(action)) {
            uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
        }
        YzDebug.d("+++++openShareFile uri:" + uri);
        if (uri != null) {
            String path = Uri.decode(uri.getEncodedPath());
            YzDebug.d("openShareFile share:" + path);
            mHomeViewModel.parseShareFile(uri);
        }
    }

    private void initView() {
        findViews();
        requestPermissions();
    }


    @Override
    protected void onPause() {
        super.onPause();
//        DataUtil.saveDspFileToDb();
    }

    private final View.OnClickListener mBottomBtnClickListener = v -> {

        Object tag = v.getTag();
        int tabId = tag != null ? Integer.parseInt(String.valueOf(tag)) : 0;

        if (tabId == 3 || tabId == 1) {//保存最后的EQCharts信息
            SPUtils.getInstance(Context.MODE_PRIVATE).put(KEY_LAST_EQCHART_TABID, tabId);
        }

        if (mTabId != tabId) {
            mCurrentFragment = mFragmentSparseArray.get(tabId);
            replaceFragment(mCurrentFragment, tabId > mTabId);
            DspSettings.CURRENT_TAB = mTabId = tabId;
        }
    };

    protected void initFragment() {
        mResTitles = getResources().getStringArray(com.qztech.sdk.R.array.btdsp_tabs);
        this.mFragmentSparseArray = new SparseArray<>();
        int i = 0;
        try {
            mPbxMainMenuRootLayout.setMenuClickListener(mBottomBtnClickListener);
            while (i < this.mTargetFragments.length) {
                BaseFragment localBaseFragment = this.mTargetFragments[i].newInstance();
//                if (localBaseFragment instanceof BaseHeadTailFragment){
//                    ((BaseHeadTailFragment)localBaseFragment).setOnBottomBtnClickListener(mBottomBtnClickListener);
//                }
                this.mFragmentSparseArray.put(i, localBaseFragment);
                i += 1;
            }
//            this.mTabId = 0;
            this.mCurrentFragment = this.mFragmentSparseArray.get(this.mTabId);
            addFragment(this.mCurrentFragment);

        } catch (Exception localException) {
            localException.printStackTrace();
        }
    }

    private void requestPermissions() {


        List<String> permissions = new ArrayList<>();
        List<String> permissionArray = new ArrayList<>();
        permissionArray.add(Manifest.permission.ACCESS_FINE_LOCATION);
        permissionArray.add(Manifest.permission.ACCESS_COARSE_LOCATION);

        String[] names = {
                "BLUETOOTH_CONNECT", "BLUETOOTH_SCAN"
        };
        for (String name : names) {
            try {
                Field field = Manifest.permission.class.getField(name);
                permissionArray.add((String) field.get(null));
            } catch (Exception e) {
            }
        }

        for (String p : permissionArray) {
            if (ContextCompat.checkSelfPermission(this, p) != PackageManager.PERMISSION_GRANTED) {
                permissions.add(p);
            }
        }
        if (permissions.size() > 0) {
            ActivityCompat.requestPermissions(this,
                    permissions.toArray(new String[permissions.size()]),
                    1);
        } else {
            initBluetooth();
        }
    }


    private void findViews() {
        findViewById(R.id.dialog_layout).setOnClickListener(v -> hideDialog());
        mPbxMainMenuRootLayout = findViewById(R.id.pbx_main_menu_root_layout);

    }


    public void initBluetooth() {
        if (mHomeViewModel.isBluetoothOpen()) {
            mHomeViewModel.searchBluetooth();
        } else {
            mHomeViewModel.openBluetooth();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu paramMenu) {
        getMenuInflater().inflate(com.hanlink.res.R.menu.menu_main, paramMenu);
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        BLog.d("onRequestPermissionsResult", permissions.toString());
        initBluetooth();
    }

    @Override
    protected void onStop() {
        uploadReceiver.pause();
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        uploadReceiver.stop();
//        DspSettings.USER_PROFILE = null;
        super.onDestroy();
    }

    @Override
    public void onDrawerItemAdded(int paramInt1, View paramView, int paramInt2, long paramLong) {
        this.mCurrentFragment.onRefreshFragment(BaseFragment.CMD_ADDED);
    }

    @Override
    public void onDrawerItemDeleted(int paramInt1, View paramView, int paramInt2, long paramLong) {
        this.mCurrentFragment.onRefreshFragment(BaseFragment.CMD_DELETED);
    }

    @Override
    public void onDrawerItemSelected(int paramInt1, View paramView, int paramInt2, long profileId) {
        try {
            DataUtil.loadData((int)profileId);
            this.mCurrentFragment.onRefreshFragment(CMD_SELECTED);
            if (!BluetoothClientManager.getInstance(this).isConnect()) {
                Toast.makeText(this, com.hanlink.res.R.string.bluetooth_error, Toast.LENGTH_SHORT).show();
                return;
            }
            mHomeViewModel.startUpload();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private RadioGroup.OnCheckedChangeListener onTabCheckedChangeListener = new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            Object tag = group.findViewById(checkedId).getTag();
            int tabId = tag != null ? Integer.parseInt(String.valueOf(tag)) : 0;
            mCurrentFragment = mFragmentSparseArray.get(tabId);

            if (mTabId != tabId) {
//                setTitle(mResTitles[tabId]);
                replaceFragment(mCurrentFragment, tabId > mTabId);
                DspSettings.CURRENT_TAB = mTabId = tabId;
//                mSaveDrawerFragment.reloadSettings();
            }
        }
    };


    private void subscribeToViewModel() {
        mHomeViewModel.mParseLiveData.observe(this, resource -> {
            if (resource != null) {
                if (resource.isLoading()) {
                    showLoadingDialog("Uploading  ...", false);
                } else if (resource.isSuccess()) {
                    mCurrentFragment.onRefreshFragment(CMD_SELECTED);
                    if (resource.data()) {
                        dismissLoading();
//                    Toast.makeText(this, R.string.read_success, Toast.LENGTH_SHORT).show();
                    }
                } else if (resource.isError()) {
                    YzDebug.d("subscribeToViewModel", resource.error());
                    Toast.makeText(this, getString(com.hanlink.res.R.string.read_fail) + resource.error().getLocalizedMessage(), Toast.LENGTH_SHORT).show();
                    dismissLoading();
                }
            }

        });
    }


    //use in fragment
    @Override
    public void readData() {
        if (!BluetoothClientManager.getInstance(getApplicationContext()).isConnect()) {
            Toast.makeText(this, com.hanlink.res.R.string.bluetooth_error, Toast.LENGTH_SHORT).show();
            return;
        }
        AskAlertDialog askAlertDialog = new AskAlertDialog(this, getString(com.hanlink.res.R.string.read_data_message), false, dialog -> {
            dialog.dismiss();
            if (!BluetoothClientManager.getInstance(this).isConnect()) {
                Toast.makeText(this, com.hanlink.res.R.string.bluetooth_error, Toast.LENGTH_SHORT).show();
                return;
            }
            mHomeViewModel.readData();
        });
        askAlertDialog.show();
    }

    //-----BluetoothEvent---------------

    /**
     * 蓝牙设备连接状态变化
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onBluetoothStateChanged(BleConnectStatusEvent event) {
        YzDebug.d("BleConnectStatusEvent:" + event.getStatus());
        switch (event.getStatus()) {
            case Constants.STATUS_DISCONNECTED:
                onDisconnected();
                break;
            case Constants.STATUS_CONNECTED:
                mHomeViewModel.sageLastConnectDevice(event.getDevice().getMac());
                onConnected(event.getDevice().getMac());
                if (DspContext.updateByConnectedDevices(event.getDevice().getName())) {
                    if (mCurrentFragment != null) {
                        mCurrentFragment.onRefreshFragment(CMD_SELECTED);
                    }
                }
                break;
        }
    }

    public HomeViewModel getHomeViewModel() {
        return mHomeViewModel;
    }

    /**
     * 连接失败
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onConnectFailed(BleConnectFailedEvent event) {
        showFail(getString(com.hanlink.res.R.string.bluetooth_connect_fail));
    }

    /**
     * 发现设备
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onFoundDevice(DeviceFoundedEvent event) {
        SearchResult searchResult = event.getDevice();
        YzDebug.d("onFoundDevice:" + event.getDevice().getName() + "  " + mIsAutoConnect);
        if (BluetoothClientManager.getInstance(this).getConnectedDevice() == null && mIsAutoConnect) {
            YzDebug.d("onFoundDevice" + searchResult.getAddress()
                    + "  " + mHomeViewModel.getLastConnectedDevice());
            if (searchResult.getAddress().equals(mHomeViewModel.getLastConnectedDevice())) {
                connect(event.getDevice().getAddress(), event.getDevice().getName());
            }
        }


        if (!mIsFoundDevice && mIsAutoConnect && BluetoothConfig.isAvailableName(event.getDevice().getName())) {

//            connect(searchResult.getAddress(), searchResult.getName());
        }
    }

    public void connect(String mac, String name) {
        mIsFoundDevice = true;
        mHomeViewModel.cancelSearch();
        showLoadingDialog(getString(com.hanlink.res.R.string.bluetooth_to_connect), false);
        mHomeViewModel.connect(mac, name);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onBluetoothStateChanged(BluetoothStateEvent event) {
        YzDebug.d("onBluetoothStateChanged:" + event.isOpenOrClosed());
        if (!event.isOpenOrClosed()) {
            mHomeViewModel.cancelSearch();
            Toast.makeText(this, com.hanlink.res.R.string.bluetooth_closed, Toast.LENGTH_SHORT).show();
        } else {
            mHomeViewModel.searchBluetooth();
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onSearchEvent(SearchStateEvent event) {
        if (!mIsAutoConnect) {
            return;
        }
        YzDebug.d("onSearchEvent:" + event.getStatus());
        switch (event.getStatus()) {
            case SearchStateEvent.SEARCH_START:
                if (mIsAutoConnect) {
                    mIsFoundDevice = false;
                }
//                showLoadingDialog(getString(R.string.bluetooth_search_device), false);
                break;
            case SearchStateEvent.SEARCH_STOP:
                if (!mIsFoundDevice) {
//                    showFail(getString(R.string.bluetooth_discover_fail));
                }
                break;
            case SearchStateEvent.SEARCH_CANCEL:
                break;
        }
    }

    private void onConnected(String mac) {
        YzDebug.d("onConnected");
        showSuccess(getResources().getString(com.hanlink.res.R.string.bluetooth_connect_successful));
        if (mCurrentFragment != null)
            mCurrentFragment.updateByConnected(true);
    }

    private void onDisconnected() {
        YzDebug.d("onDisconnected");
        mHomeViewModel.cancelReadData();
        if (mCurrentFragment != null)
            mCurrentFragment.updateByConnected(false);
        showFail(getResources().getString(com.hanlink.res.R.string.bluetooth_disconnect));
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        MenuItem menuItem = menu.findItem(com.hanlink.res.R.id.action_settings);
        if (menuItem != null) {
            menuItem.setIcon(BluetoothClientManager.getInstance(getApplicationContext()).isConnect() ? com.hanlink.res.R.drawable.ic_settings_checked : com.hanlink.res.R.drawable.ic_settings);
        }
        return super.onPrepareOptionsMenu(menu);
    }

    public void resetAppAsk() {
        AskAlertDialog askAlertDialog = new AskAlertDialog(this, getString(com.hanlink.res.R.string.read_data_ask_sure), false, dialog -> {
            dialog.dismiss();
            resetApp();
        });
        askAlertDialog.show();
    }

    private void resetApp() {
        mHomeViewModel.resetApp();
//        mDrawLayout.closeDrawer(Gravity.END);
        mCurrentFragment.onRefreshFragment(CMD_SELECTED);
        DspSettings.reset = false;
        DataUtil.saveSummingSettingsToDb();
        DataUtil.saveXoverSettingsToDb();
        DataUtil.saveEqSettingsToDb();
        DataUtil.saveAdvanceSettingsToDb();
    }

    @Override
    public void onBackPressed() {
        if (mCurentDialogFragment != null) {
            hideDialog();
        } else {
            super.onBackPressed();
        }

    }

    @Override
    public void showSaveDialog(boolean isHorizontal) {
        showDialog(new SaveDialogFragment(), isHorizontal);
    }

    @Override
    public void showDeviceDialog(boolean isHorizontal) {
        showDialog(new DeviceDialogFragment(), isHorizontal);
    }

    private BaseFragment mCurentDialogFragment;

    private void showDialog(BaseFragment fragment, boolean isHorizontal) {
        mCurentDialogFragment = fragment;
        Bundle args = new Bundle();
        args.putBoolean("IS_HORIZONTAL", isHorizontal);
        fragment.setArguments(args);
        final ViewGroup layout = findViewById(R.id.dialog_layout);
        if (layout == null) return;
        layout.setVisibility(View.VISIBLE);
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.dialog_layout, fragment)
                .commit();
    }

    private void hideDialog() {
        if (mCurentDialogFragment == null)
            return;
        getSupportFragmentManager()
                .beginTransaction()
                .remove(mCurentDialogFragment)
                .commit();
        mCurentDialogFragment = null;
        final ViewGroup layout = findViewById(R.id.dialog_layout);
        layout.removeAllViews();
        if (layout == null) return;
        layout.setVisibility(View.GONE);
    }


    //===================================================
    private PbxLoadingDialog mPbxLoadingDialog;

    @Override
    protected void createDialogIfNull() {
        if (mPbxLoadingDialog == null) {
            mPbxLoadingDialog = new PbxLoadingDialog(this);
            mPbxLoadingDialog.setOnDismissListener(dialog -> {
                mPbxLoadingDialog = null;
            });
        }
    }

    @Override
    public void showLoadingDialog(String msg, boolean isCancelable) {
        createDialogIfNull();
        mPbxLoadingDialog.setOnDismissListener(null);
        mPbxLoadingDialog.setMessage(msg, PbxOutputSelectChannelsLayout.sColorSelected);
        mPbxLoadingDialog.setCancelable(isCancelable);
        mPbxLoadingDialog.setCanceledOnTouchOutside(isCancelable);
        if (!mPbxLoadingDialog.isShowing()) {
            mPbxLoadingDialog.showLoading();
        }
    }


    @Override
    protected void showSuccess(String errorMsg) {
        createDialogIfNull();
        mPbxLoadingDialog.showSuccess(errorMsg);
        mPbxLoadingDialog.setOnDismissListener(dialog -> {
            readData();
        });
    }

    @Override
    protected void showFail(String errorMsg) {
        createDialogIfNull();
        mPbxLoadingDialog.setOnDismissListener(null);
        mPbxLoadingDialog.showFail(errorMsg);
    }

    @Override
    public void dismissLoading() {
        if (mPbxLoadingDialog != null && mPbxLoadingDialog.isShowing()) {
            mPbxLoadingDialog.dismiss();
        }
    }

    int index = 0;
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onRead(NotifyDataReadEvent event) {
//        if (tv == null){
//            tv = findViewById(R.id.log);
//        }
//        if (tv != null){
//            if (index >= 25){
//                index = 0;
//                tv.setText(event.getLen() +" : " + event.getData() +"\n");
//            }else{
//                tv.append(event.getLen() + " : " + event.getData() + "\n");
//            }
//
//            index ++;
//        }

    }
    private TextView tv;
}
